﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProjectTemplateUpdater
{
	public class ProjectTemplateZipUpdater
	{
		private string styleMVVMString = "<package id=\"StyleMVVM\" version=\"{0}\" />";
		private string styleMVVMControlString = "<package id=\"StyleMVVM.CSharp\" version=\"{0}\" />";
		private string styleMVVMCSharpString = "<package id=\"StyleMVVM.Controls\" version=\"{0}\" />";
		private string styleMVVMConventionsString = "<package id=\"StyleMVVM.Conventions\" version=\"{0}\" />";
		private string styleMVVMMVCString = "<package id=\"StyleMVVM.MVC4\" version=\"{0}\" />";
		private string styleMVVMWCFString = "<package id=\"StyleMVVM.WCF\" version=\"{0}\" />";

		private string oldVersionString;
		private string newVersionString;
		private string templatePath;
		private string savePath;

		public ProjectTemplateZipUpdater(string oldVersionString, string newVersionString, string templatePath, string savePath)
		{
			this.oldVersionString = oldVersionString;
			this.newVersionString = newVersionString;
			this.savePath = savePath;
			this.templatePath = templatePath;
		}

		public void Process()
		{
			using (FileStream openFile = new FileStream(templatePath, FileMode.Open))
			{
				using (ZipArchive openZip = new ZipArchive(openFile, ZipArchiveMode.Read))
				{
					using (FileStream newFile = new FileStream(savePath, FileMode.Create))
					{
						using (ZipArchive archive = new ZipArchive(newFile, ZipArchiveMode.Create))
						{
							foreach (ZipArchiveEntry zipArchiveEntry in openZip.Entries)
							{
								MemoryStream fullFile = new MemoryStream();

								using (Stream readStream = zipArchiveEntry.Open())
								{
									byte[] buffer = new byte[8192];
									int readLength;

									while ((readLength = readStream.Read(buffer, 0, buffer.Length)) > 0)
									{
										fullFile.Write(buffer, 0, readLength);
									}
								}

								ZipArchiveEntry newEntry = archive.CreateEntry(zipArchiveEntry.FullName);

								byte[] totalBytes = null;

								if (zipArchiveEntry.FullName.EndsWith(".vstemplate"))
								{
									totalBytes = ReplaceVersionString(fullFile);
								}
								else
								{
									totalBytes = fullFile.ToArray();
								}

								using (Stream openNewStream = newEntry.Open())
								{
									openNewStream.Write(totalBytes, 0, totalBytes.Length);
								}
							}
						}
					}
				}
			}
		}

		private byte[] ReplaceVersionString(MemoryStream memoryStream)
		{
			byte[] fileBytes = memoryStream.ToArray();
			string fileString = Encoding.UTF8.GetString(fileBytes);
			string outputString = fileString;

			outputString = outputString.Replace(string.Format(styleMVVMString, oldVersionString),
										string.Format(styleMVVMString, newVersionString));

			outputString = outputString.Replace(string.Format(styleMVVMControlString, oldVersionString),
										string.Format(styleMVVMControlString, newVersionString));

			outputString = outputString.Replace(string.Format(styleMVVMCSharpString, oldVersionString),
										string.Format(styleMVVMCSharpString, newVersionString));

			outputString = outputString.Replace(string.Format(styleMVVMConventionsString, oldVersionString),
										string.Format(styleMVVMConventionsString, newVersionString));

			outputString = outputString.Replace(string.Format(styleMVVMMVCString, oldVersionString),
										string.Format(styleMVVMMVCString, newVersionString));

			outputString = outputString.Replace(string.Format(styleMVVMWCFString, oldVersionString),
							string.Format(styleMVVMWCFString, newVersionString));

			return Encoding.UTF8.GetBytes(outputString);
		}
	}
}
